
public class BitmapCmd {
	static interface CmdType{
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap);
	}
	
	static public final CmdType CMD_Initialize = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			//for convenient index 0 is not used 
			bitmap = new char[cmd.mX1 + 1][cmd.mY1 + 1];
			clearAll(bitmap);
			return bitmap;			
		};
	};
	
	static public final CmdType CMD_Clear = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			clearAll(bitmap);
			return bitmap;
		}
	};
	
	static public final CmdType CMD_DrawPoint = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			bitmap[cmd.mX1][cmd.mY1] = cmd.mColor;
			return bitmap;			
		}
	};
	
	static public final CmdType CMD_DrawV = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			drawV(bitmap, cmd.mX1, cmd.mY1, cmd.mY2, cmd.mColor);
			return bitmap;
		}
	};
	
	static public final CmdType CMD_DrawH = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			drawH(bitmap, cmd.mX1, cmd.mX2, cmd.mY1, cmd.mColor);
			return bitmap;
		}
	};

	static public final CmdType CMD_DrawRectangle = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			drawV(bitmap, cmd.mX1, cmd.mY1, cmd.mY2, cmd.mColor);
			drawV(bitmap, cmd.mX2, cmd.mY1, cmd.mY2, cmd.mColor);
			
			drawH(bitmap, cmd.mX1, cmd.mX2, cmd.mY1, cmd.mColor);
			drawH(bitmap, cmd.mX1, cmd.mX2, cmd.mY2, cmd.mColor);
			
			return bitmap;
		}
	};
	
	static public final CmdType CMD_FillArea = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			findAreaBound(bitmap, cmd);
			fillArea(bitmap, cmd.mX1, cmd.mX2, cmd.mY1, cmd.mY2, cmd.mColor);
			
			return bitmap;
		}
	};
	
	static public final CmdType CMD_Print = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			System.out.println(cmd.mFilename);
			
			for(int i = 0; i < bitmap.length; ++i) {
				System.out.println(bitmap[i]);				
			}
			
			return bitmap;
		}
	};
	
	static public final CmdType CMD_Exit = new CmdType(){
		public char[][] executeCmd(BitmapCmd cmd, char[][] bitmap) {
			clearAll(bitmap);
			
			return bitmap;
		}
	};
	
	
/*==============================================================*/
	static private void clearAll(char[][] bitmap){
		fillArea(bitmap, 1, bitmap.length - 1, 1, bitmap[0].length - 1, 'O');
	}
	
	static private void fillArea(char[][] bitmap, int x1, int x2, int y1, int y2, char color){
		for(int i = x1; i <= x2; ++i) {
			for(int j = y1; j <= y2; ++j) {
				bitmap[i][j] = color;
			}
		}
	}
	
	static private void drawH(char[][] bitmap, int x1, int x2, int y, char color){
		for(int i = x1; i <= x2; ++i)
			bitmap[i][y] = color;
	}
	
	static private void drawV(char[][] bitmap, int x, int y1, int y2, char color){
		for(int i = y1; i <= y2; ++i)
			bitmap[x][i] = color;
	}
	
	public CmdType mCommend;
	
	public int mX1;
	public int mX2;
	
	public int mY1;
	public int mY2;
	
	public char mColor;
	public String mFilename;
}
